package vn.gq.udv.utils;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.zip.GZIPInputStream;
import org.apache.http.HttpStatus;
import org.json.JSONException;
import org.json.JSONTokener;

import vn.gq.udv.comic.BuildConfig;
import android.content.Context;
import android.util.Log;


public class Client extends AsyncTask<String, Integer, Object>{
	
	public static long mCacheTimeExpired = 864000000;		// cache 1 day
	
	private DataType dataType = DataType.NORMAL;
	private ClientListener mClientListener;
	private int errorCode = 0;
	private Context mContext;
	private NetworkOption networkOption = NetworkOption.OPTION_USE_NETWORK;
	
	public enum DataType {
		GZIP, NORMAL, BASE64GZIP, JSON, GZIPJSON
	}
	
	public Client(Context context) {
		mContext = context;
	}
	
	public void setEncodingType(DataType dataType) {
		this.dataType = dataType;
	}
	
	public void setCacheExpired(long time) {
		mCacheTimeExpired = time;
	}
	
	public void setNetworkOption(NetworkOption option) {
		networkOption = option;
	}

	
	private Object processData(InputStream is) throws JSONException {
		Object output = IOUtils.convertStreamToString(is);
		if (dataType == DataType.GZIPJSON || (dataType == DataType.JSON)) {
			output = (Object) new JSONTokener((String) output).nextValue();
		}
		return output;
	}
	
	@Override
	protected Object doInBackground(String... params) {
		String url = params[0];
		HttpURLConnection connection = null;
		Object output = null;
		URL uri;
		try {
			uri = new URL(url);
			InputStream is = null;
			CacheManager cacheManager = CacheManager.getInstance(mContext);
			if (networkOption == NetworkOption.OPTION_USE_CACHE) {
				is = cacheManager.getCache(uri);
			}
			if (is == null || (networkOption == NetworkOption.OPTION_USE_NETWORK)) {
				
				if (BuildConfig.DEBUG) {
					Log.i("longhoanggiang", "------------start load: "+url);
				}
				connection = (HttpURLConnection) uri.openConnection();
				connection.setRequestMethod("GET");
				connection.connect();
				int code = connection.getResponseCode();
				if (code == HttpStatus.SC_OK) {
					switch(dataType) {
						case GZIPJSON:
						case BASE64GZIP:
						case GZIP:
							is = new GZIPInputStream(connection.getInputStream());
							break;
						default:
							is = connection.getInputStream();
							break;
					}
				} else {
					errorCode = code;
				}
				is = cacheManager.putCache(uri, is, System.currentTimeMillis() + mCacheTimeExpired);
			}
			output = processData(is);
		} catch (MalformedURLException e) {
			errorCode = 1;
			e.printStackTrace();
		} catch (IOException e) {
			errorCode = 2;
			e.printStackTrace();
		} catch (JSONException e) {
			errorCode = 3;
			e.printStackTrace();
		} finally { 
			if (connection != null) {
				connection.disconnect();
			}
		}
		return output;
	}
	
	public void executeAndListener(String url, ClientListener listener) {
		mClientListener = listener;
		execute(url);
	}
	
	@Override
	protected void onPostExecute(Object result) {
		if (mClientListener != null) {
			mClientListener.onDone(errorCode, result);
		}
	}



	public abstract class ClientListener {
		public abstract void onDone(int errorCode, Object data);
	}
	
	
}
